import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query, Req } from '@nestjs/common';
import { BaseController } from '../../base/base.controller';
import { RoleService } from './role.service';
import { AddDto, PageDto } from './dto';
import { FindOptionsWhere } from 'typeorm';
import { DtoPipe } from '../../pipes/dto/dto.pipe';
import { Role } from '@app/db/common/entities/Role';

@Controller('role')
export class RoleController extends BaseController{
    constructor(
        private readonly service:RoleService,
    ){
        super()
    }

    @Get('list')
    async list(@Req() { userId }) {
        const list = await this.service.db.role.find({creatorId : userId}, null, null, null, {sort : 'ASC', id : 'ASC'})
        return this.successRes(list)
    }

    @Get('page')
    async rolePage(@Query() dto:PageDto, @Req() { userId }) {
        let result:PaginationResult<Role> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<Role> = {
            creatorId : userId
        }

        result.total = await this.service.db.role.count(where)

        if(result.total > 0) {
            result.rows = await this.service.db.role.pagination(dto.pageNo, dto.pageSize, where, null, {sort : 'ASC', id : 'DESC'})
        }

        return this.successRes(result)

    }

    @Post('add')
    async add(@Body(new DtoPipe()) dto:AddDto, @Req() { userId, locale }) {
        //判断是否存在了相同名称的角色
        if(true == await this.service.db.role.isExistsByWhere({name : dto.name, creatorId : userId})) {
            return this.failRes("名称已存在")
        }
        
        const res = await this.service.db.role.insert({...dto, creatorId : userId, createTime : this.utils.time()})
        return res ? this.successRes(res.rows) : this.failRes()
    }

    @Put('update/:id')
    async edit(@Body(new DtoPipe({skipNullProperties : true})) dto:AddDto, @Param('id', ParseIntPipe) id:number, @Req() { userId, locale }) {
        if(id <= 0) return

        let fields = Object.keys(dto) as (keyof Role)[]
        if(fields.length == 0) return
        fields.push('creatorId')


        const role = await this.service.db.role.findOne({ id }, fields)
        
        if(!role || role.creatorId != userId) return

        let updateData:KeyToValueType<Role> = {}

        delete role.creatorId

        for(let k in role) {
            if(k == 'menus') {
                if(JSON.stringify(role.menus) == JSON.stringify(dto.menus)) continue
            }
            if(role[k] == dto[k]) continue

            updateData[k] = dto[k]
        }

        if(Object.keys(updateData).length == 0) return this.successRes()

        if(updateData.name && (true == await this.service.db.role.isExistsByWhere({name : updateData.name, creatorId : userId}))) {
            return this.failRes("名称已存在")
        }

        const res = await this.service.db.role.update({id : id}, updateData)
        return res === 0 ? this.failRes() : this.successRes()
    }

    @Delete('delete/:id')
    async del(@Param('id', ParseIntPipe) id:number, @Req() { userId }) {
        if(id <= 0) return
        let role = await this.service.db.role.findOne({ id }, ['creatorId'])
        if(!role || role.creatorId != userId) return
        const res = await this.service.db.role.delete({id : id})
        return res === 0 ? this.failRes() : this.successRes()
    }

}
